home *** CD-ROM | disk | FTP | other *** search
-
- ; LZSTUB.ASM -- LZSS self-extract pgm
- ; June 2, 1989
- ;
- ; $Log: RCS/LZSTUB.ASM $
- ;
- ; revision 1.5 MAS 89/06/02 03:47:58
- ; ask overwrite.
- ; exec autolarc.bat
- ; check crc.
- ;
- ; revision 1.4 MAS 89/01/31 04:24:52
- ; for LArc 3.XX (-lz4-, -lz5-)
- ; check disk-full.
- ;
- ; revision 1.3 MAS 88/07/10 20:44:12
- ; getbit made quick.
- ; all segment bugs fixed.
- ;
- ; revision 1.2 MAS 88/06/18 22:05:59
- ; generate .exe file.
- ; some bugs (esp. segment check) fixed.
- ; smaller output buffer.
- ;
- ; revision 1.1 MAS 88/05/22 17:44:54
- ; Initial revision
- ;
- ;
- include lms.inc ;; V2.3 by SO ;; cf. break1, break2
- ;
- MINLEN = 3 ; THRESHOLD + 1.
- N = 4096 ; buffer size 2^12.
- F = 15+MINLEN ; lookahead buffer size.
- ;
- crc16 = 0a001h
- BUFHEAD = N ; output buffer head addr.
- BUFSIZ = 2000h ; output buffer size (maximum)
- CRCHEAD = BUFHEAD+BUFSIZ
- CRCSIZ = 512 ; 256*2
- WRKHEAD = CRCHEAD+CRCSIZ
- ;
- lzhead struc
- headsiz db ?
- headchk db ?
- headid db 5 dup (?) ; '-lz4-' '-lz5-'
- ssize dd ?
- dsize dd ?
- time dw ?
- date dw ?
- attr dw ?
- fnlen db ?
- lzhead ends
- ;
- work struc
- count dd ? ; size of source.
- fhandl dw ?
- bufptr dw ?
- curcrc dw ?
- orgcrc dw ?
- work ends
- ;
- autol struc
- db 8, "AUTOLARC"
- ;
- autosw db ".BAT"
- ;
- autol ends
- ;
- pushs macro regs
- irp areg, <regs>
- push areg
- endm
- endm
- ;
- pops macro regs
- irp areg, <regs>
- pop areg
- endm
- endm
- ;
- movsr macro dst, src
- push src
- pop dst
- endm
- ;
- msdos macro num
- ifnb <num>
- if num ge 100h
- mov ax, num
- else
- mov ah, num
- endif
- endif
- int 21h
- endm
- ;
- code segment byte public
- assume cs:code
- ;
- zero label byte
- ;
- ; -------- print messages -------------
- ;
- open_msg db "LZSS self extract" ; must org 0.
- crlf_msg db 0dh, 0ah, "$"
- wrt_err_msg db "write error$"
- open_err_msg db "can't open$"
- already_msg db "exists. Overwrite[y/n]$"
- crc_err_msg db 7, "fails crc$"
- ;
- ; -------- autolarc -------------------
- ;
- autolarc autol <>
- ;
- checkcrc:
- mov ax, [bp].orgcrc
- cmp [bp].curcrc, ax
- mov dx, offset crc_err_msg
- jnz print
- ret
- ;
- crlf: mov dx, offset crlf_msg
- ;
- print:
- ifdef LARGE
- push ds
- movsr ds, cs
- msdos 9
- pop ds
- ;
- else
- msdos 9
- endif
- ;
- ret
- ;
- putc: push dx
- xchg ax, dx
- msdos 2
- pop dx
- ret
- ;
- eject_err:
- mov dx, offset wrt_err_msg
- print_err:
- call print
- call crlf
- msdos 4c01h ; error exit
- ;
- ;----------------------------------------
- ; output to file
- ;----------------------------------------
- ;
- ; fputc --
- ; in al = char. destroy nothing.
- ;
- fputc proc
- push di
- mov di, [bp].bufptr
- ;
- .if <di ae BUFSIZ+BUFHEAD>
- call eject
- mov di, BUFHEAD
- .endif
- ;
- stosb
- mov [bp].bufptr, di
- pop di
- ret
- ;
- fputc endp
- ;
- ; Eject - destroy nothing.
- ;
- eject proc
- pushs <ds,si,dx,cx,bx,ax>
- .do
- movsr ds, es
- mov si, BUFHEAD
- mov cx, [bp].bufptr
- sub cx, si
- jz break1
- pushs <si, cx> ; si = buffer
- mov dx, [bp].curcrc ; dx = crc
- .do
- lodsb
- xor al, dl ; crc and $FF xor c
- mov ah, 0
- shl ax, 1
- xchg bx, ax
- mov dl, dh ; crc shr 8
- mov dh, 0
- xor dx, es:[bx]+CRCHEAD ; xor crctable
- .loop
- mov [bp].curcrc, dx
- pops <cx, dx>
-
- mov bx, [bp].fhandl
- msdos 40h ; write to file
- jc eject_err ; error or
- cmp ax, cx ; disk full
- jnz eject_err
- mov al, '.'
- call putc
- .until
- ;
- break1: pops <ax,bx,cx,dx,si,ds>
-
- eject_exit:
- ret
- ;
- eject endp
- ;
- ;---------------------------------------;
- ; decoder. ;
- ; in ds:si = lzs data start -1 ;
- ; out ds:si ;
- ; destroy all ;
- ;---------------------------------------;
- ;
- decode proc
- xor di, di
- mov al, 0
- .do
- mov cx, 0dh
- rep stosb
- inc al
- .until <z>
- .do
- stosb
- inc al
- .until <z>
- .do
- dec al
- stosb
- .until <z>
- mov cx, 80h
- push cx
- rep stosb
- pop cx
- mov al, ' '
- rep stosb
- mov di, N-F
- mov dl, 80h ; mask 1,2,4,8,..80h
- .while
- rol dl, 1
- ;
- .if <c>
- call getc
- jc eject_exit
- mov dh, al ; flags.
- .endif
- ;
- call getc
- jc eject_exit
- test dh, dl ; if flag on then 1 char.
- ;
- .if <nz>
- call fputc ; fputc(c)
- stosb ; buf[di] := c; di := (di+1) mod N
- and di, N-1
- .continue
- .endif
- ;
- xchg bx, ax ; (bl=al)
- call getc ; else cx := len, bx := po;
- jc eject_exit
- mov bh, al ; ( pos = lo + hi&f0h >>4 )
- mov cl, 4
- shr bh, cl
- and ax, 0fh ; ( len = (hi & 0fh) + MINLEN )
- add al, MINLEN
- xchg cx, ax
- .do
- mov al, es:[bx]
- call fputc
- inc bx
- and bh, (N-1) shr 8
- stosb
- and di, N-1
- .loop
- .enddo
- ;
- decode endp
- ;
- ; Getc
- ; in-out ds:si = pos. out al = c, CF = eof.
- ; destroy ah
- ;
- getc proc
- ifdef LARGE
- sub word ptr [bp].count, 1
- sbb word ptr [bp].count+2, 0
- .if <nc>
- inc si
- .if <z>
- mov ax, ds
- add ax, 1000h ; 0:ffff(0ffff)+1 = 1000:0 (10000)
- mov ds, ax
- .endif
- else
- sub word ptr [bp].count, 1
- .if <nc>
- inc si
- endif
- mov al, [si]
- clc
- .endif
- ret
- getc endp
- ;
- ;-------------------------------;
- ; main program. ;
- ;-------------------------------;
- ;
- begin: cld
- push ds ; use to exec autolarc.
- movsr es, ss ; es(work/output buffer) = ss.
- movsr ds, cs ; initial value of ds = cs.
- mov bp, WRKHEAD ; bp = work area ptr.
- xor dx, dx ; open msg
- call print
- mov di, CRCHEAD
- xor dx, dx
- .do
- mov ax, dx
- mov cx, 8
- .do
- shr ax, 1
- .if <c>
- xor ax, crc16
- .endif
- .loop
- stosw
- inc dl
- .until <z>
- mov si, offset memend
- ;
- main_loop:
- .if <[si].headsiz e 0>
- pop es ; PSP segment.
- mov bx, ((main_next-zero)+15)/16 + 10h ; 10h for PSP.
- msdos 4ah ; resize memory block.
- ifdef LARGE
- movsr ds, cs
- endif
- mov si, offset autolarc
- .if <[si].autosw ne '.'> ; autolarc exist?
- int 2eh ; execute command.
- .endif
- msdos 4c00h ; terminate program.
- .endif
- ;
- main_next label near
- pushs <es, si>
- lea si, [si].fnlen ; change name to asciz
- mov di, si
- mov dx, si ; for open function call
- lodsb
- mov ah, 0
- xchg cx, ax
- movsr es, ds
- rep movsb
- mov ax, [di+1] ; get crc
- mov [bp].orgcrc, ax
- mov byte ptr [di], '$' ; print file name
- msdos 9
- mov al, ' '
- call putc
- mov byte ptr [di], 0 ; to asciz
- mov di, offset autolarc+1 ; check autolarc
- ifdef LARGE
- movsr es, cs
- endif
- mov si, dx
- mov cx, (type autol)-1
- repe cmpsb
- pops <si, es>
- push dx
- .do
- .if <z>
- ;
- ifdef LARGE
- mov byte ptr cs:[di]-4, 0dh
- else
- mov byte ptr [di]-4, 0dh
- endif
- ;
- .else
- msdos 3d00h ; open for input
- jc break2
- xchg bx, ax ; bx=file handle
- msdos 3eh ; close
- mov dx, offset already_msg
- call print
- .do
- mov dl, 0ffh
- msdos 6
- and al, 0dfh ; upcase
- cmp al, 'Y'
- jz break2
- .until <al e 'N'>
- call putc
- pop dx
- jmp short main_skip
- .endif
- .until
- ;
- break2: pop dx
-
- xor cx, cx
- msdos 3ch ; create
- .if <c>
- mov dx, offset open_err_msg
- jmp print_err
- .endif
- mov [bp].fhandl, ax ; init output
- mov [bp].bufptr, BUFHEAD
- mov [bp].curcrc, 0
- mov ax, word ptr [si].ssize ; init input
- mov word ptr [bp].count, ax
- ;w
- ifdef LARGE
- mov ax, word ptr [si].ssize+2
- mov word ptr [bp].count+2, ax
- push ds
- endif
- ;
- push si
- mov bl, [si].headid+3 ; '4' or '5'
- call srchead
- add si, ax
- dec si
- shr bl, 1
- .if <nc>
- .while
- call getc ; Storing
- jc decode45
- call fputc
- .enddo
- .endif
- call decode ; Main
- ;
- decode45:
- call eject
- pop si
- ;
- ifdef LARGE
- pop ds
- endif
- ;
- mov bx, [bp].fhandl
- mov cx, [si].time ; set date/time
- mov dx, [si].date
- msdos 5701h
- msdos 3eh ; close file.
- mov cx, [si].attr ; change file attr.
- lea dx, [si].fnlen
- msdos 4301h
- call checkcrc
- ;
- main_skip:
- call crlf
- ;
- ; ds:si += (ssize + headsiz + 2)
- ;
- call srchead
- ;
- ifdef LARGE
- mov bx, word ptr [si].ssize+2
- mov cl, 12
- shl bx, cl
- add ax, word ptr [si].ssize
- mov dx, ds
- adc dx, bx
- add si, ax
- .if <c>
- add dh, 10h
- .endif
- ;
- mov ax, si ; Normalize pointer
- mov cl, 4
- shr ax, cl
- add dx, ax ; ds = ds + (si div 16)
- and si, 15 ; si = si mod 16
- mov ds, dx
- ;
- else
- add ax, word ptr [si].ssize
- add si, ax
- endif
- ;
- jmp main_loop
- ;
- srchead proc
- mov al, [si].headsiz
- mov ah, 0
- inc ax
- inc ax
- ret
- srchead endp
- ;
- memend label byte
- ;
- code ends
- ;
- stack segment word stack
- ;
- db WRKHEAD+200 dup (?)
- ;
- stack ends
- ;
- end begin